package com.hibox.controller;


import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.*;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hibox.common.annotation.Anonymous;
import com.hibox.common.core.domain.AjaxResult;
import com.hibox.common.core.redis.RedisCache;
import com.hibox.common.utils.DateUtils;
import com.hibox.common.utils.SecurityUtils;
import com.hibox.common.utils.ServletUtils;
import com.hibox.common.utils.StringUtils;
import com.hibox.common.utils.http.HttpUtils;
import com.hibox.common.utils.ip.AddressUtils;
import com.hibox.common.utils.ip.IpUtils;
import com.hibox.common.utils.uuid.IdUtils;
import com.hibox.constant.MemberConstant;
import com.hibox.domain.Member;
import com.hibox.framework.web.domain.server.Mem;
import com.hibox.service.MemberService;

import javax.annotation.Resource;
import javax.xml.transform.Result;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.hibox.util.*;
import com.hibox.vo.LoginVo;
import com.hibox.vo.RegisterVo;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

/**
 * 会员表(Member)表控制层
 *
 * @author WangFK
 * @since 2023-08-17 16:30:24
 */
@RestController
@RequestMapping("/store/member")
public class MemberController {
    /**
     * 服务对象
     */
    @Resource
    private MemberService memberService;
    @Resource
    private QiniuUtils qiniuUtils;
    @Resource
    private RedisCache redisCache;
//    @Resource
//    private MessageSendUtil messageSendUtil;


    /**
     * 登出
     *
     * @param id
     * @return
     */
    @Anonymous
    @GetMapping("/logout")
    public AjaxResult logout(String id) {
        String key = MemberConstant.MEMBER_INFO + id;
        redisCache.deleteObject(key);
        return AjaxResult.success();
    }

    /**
     * 昵称 手机号 邮箱 密码
     *
     * @param registerVo
     * @return
     */
    @Anonymous
    @PostMapping("/register")
    public AjaxResult register(@RequestBody RegisterVo registerVo) {
        Member member = new Member();
        String code = registerVo.getCode();
        String key = "";
        String password = "";
        String phone = registerVo.getPhone();
        String email = registerVo.getEmail();
        String nickName = registerVo.getNickName();
        if (ObjectUtil.isEmpty(nickName) || ObjectUtil.isEmpty(code)) {
            return AjaxResult.error("请按规范填写");
        }
        if (ObjectUtil.isEmpty(registerVo.getPassword())) {
            password = SecurityUtils.encryptPassword("88888888");
        }
        // 昵称
        member.setNickName(nickName);
        // 账号
        member.setMemberName("Hi-Box_" + IdUtils.fastSimpleUUID());
        // 未指定 密码默认8888888
        member.setPassword(password);


        if (ObjectUtil.isNotEmpty(phone)) {
            if (!PhoneUtil.isPhone(phone)) {
                return AjaxResult.error("手机号格式错误");
            }
            LambdaUpdateWrapper<Member> lqw = new LambdaUpdateWrapper<Member>()
                    .eq(Member::getPhone, phone);
            if (ObjectUtil.isNotEmpty(memberService.list(lqw))) {
                return AjaxResult.error("手机号:" + phone + "重复");
            }
            String phoneAddress = PhoneAddress.getPhoneAddress(phone);
            // 手机号 归属地
            member.setPhone(phone);
            member.setPhoneAddress(phoneAddress);
            key = MemberConstant.MEMBER_CODE + phone;
        }
        if (ObjectUtil.isNotEmpty(email)) {
            if (!MailUtil.isEmailInvalid(email)) {
                return AjaxResult.error("邮箱格式错误");
            }
            LambdaUpdateWrapper<Member> lqw = new LambdaUpdateWrapper<Member>()
                    .eq(Member::getEmail, email);
            if (ObjectUtil.isNotEmpty(memberService.list(lqw))) {
                return AjaxResult.error("邮箱:" + email + "重复");
            }
            member.setEmail(email);
            key = MemberConstant.MEMBER_CODE + email;
        }

        String value = redisCache.getCacheObject(key);

        if (ObjectUtil.isEmpty(value)) {
            return AjaxResult.error("请重新发送验证码");
        }
        if (!value.equalsIgnoreCase(code)) {
            return AjaxResult.error("请输入正确验证码");
        }
        redisCache.deleteObject(key);

        memberService.save(member);
        member = updateIPMessageByMemberId(member.getId());
        String keyMember = MemberConstant.MEMBER_INFO + member.getId();
        redisCache.setCacheObject(keyMember, member, 1, TimeUnit.HOURS);
        return AjaxResult.success(member);

    }

    /**
     * 发送验证码
     */
    @Anonymous
    @PostMapping("/sendCode")
    public AjaxResult SendCode(@RequestBody LoginVo loginVo) {
        String phone = loginVo.getPhone();
        String email = loginVo.getEmail();
        String code = RandomUtil.randomNumbers(4);
        String key = MemberConstant.MEMBER_CODE;
        if (ObjectUtil.isNotEmpty(phone)) {
            if (!PhoneUtil.isPhone(phone)) {
                return AjaxResult.error("手机号格式不正确");
            }
            key += phone;
        }
        if (ObjectUtil.isNotEmpty(email)) {
            if (!MailUtil.isEmailInvalid(email)) {
                return AjaxResult.error("邮箱格式不正确");
            }
            key += email;
        }
        String value = redisCache.getCacheObject(key);
        if (ObjectUtil.isNotEmpty(value)) {
            return AjaxResult.warn("验证码已发出,请勿重复操作");
        }
        redisCache.setCacheObject(key, code, 5, TimeUnit.MINUTES);
        if (ObjectUtil.isNotEmpty(phone)) {
//            messageSendUtil.SendMsg(phone, code);
        } else {
            MailUtil.sendHtml(email, code);
        }
        return AjaxResult.success();

    }

    /**
     * 会员登陆 手机号 邮箱
     *
     * @param loginVo
     * @return
     */
    @Anonymous
    @PostMapping("/login")
    public AjaxResult MemberLoginbyPhone(@RequestBody LoginVo loginVo) {
        String phone = loginVo.getPhone();
        String email = loginVo.getEmail();
        String code = loginVo.getCode();
        String value = "";
        String key = MemberConstant.MEMBER_CODE;
        LambdaUpdateWrapper<Member> lqw = new LambdaUpdateWrapper<Member>();
        if (ObjectUtil.isEmpty(code)) {
            return AjaxResult.error("请将信息填写完整");
        }
        if (ObjectUtil.isNotEmpty(phone)) {
            if (!PhoneUtil.isPhone(phone)) {
                return AjaxResult.error("手机号格式不正确");
            }
            key += phone;
        }
        if (ObjectUtil.isNotEmpty(email)) {
            if (!MailUtil.isEmailInvalid(email)) {
                return AjaxResult.error("邮箱格式不正确");
            }
            key += email;
        }
        value = redisCache.getCacheObject(key);

        if (ObjectUtil.isEmpty(value)) {
            return AjaxResult.error("请先注册");
        }
        if (!value.equalsIgnoreCase(code)) {
            return AjaxResult.error("请输入正确验证码");
        }
        redisCache.deleteObject(key);
        if (ObjectUtil.isNotEmpty(phone)) {
            lqw.eq(Member::getPhone, phone);
        } else {
            lqw.eq(Member::getEmail, email);
        }
        List<Member> list = memberService.list(lqw);
        Member member = list.get(0);
        if (list.size() != 1) {
            return AjaxResult.error("用户不存在");
        }
        if ("1".equals(member.getStatus())) {
            return AjaxResult.error("账号冻结,联系管理员");
        }
        member = updateIPMessageByMemberId(member.getId());
        String keyMember = MemberConstant.MEMBER_INFO + member.getId();
        redisCache.setCacheObject(keyMember, member, 1, TimeUnit.HOURS);
        return AjaxResult.success(member);

    }

    /**
     * 会员登陆 用户名
     *
     * @param loginVo
     * @return
     */
    @Anonymous
    @PostMapping("/login/byMemberName")
    public AjaxResult MemberLogin(@RequestBody LoginVo loginVo) {
        String memberName = loginVo.getMemberName();
        String password = loginVo.getPassword();
        if (ObjectUtil.isEmpty(memberName) || ObjectUtil.isEmpty(password)) {
            return AjaxResult.error("用户名或密码为空");
        }
        LambdaUpdateWrapper<Member> lqw = new LambdaUpdateWrapper<Member>()
                .eq(Member::getMemberName, memberName);
        List<Member> list = memberService.list(lqw);
        if (list.size() != 1) {
            return AjaxResult.error("用户不存在");
        }
        Member member = list.get(0);
        if (!SecurityUtils.matchesPassword(password, member.getPassword())) {
            return AjaxResult.error("用户名或密码为错误");
        }
        if ("1".equals(member.getStatus())) {
            return AjaxResult.error("账号冻结,联系管理员");
        }
        member = updateIPMessageByMemberId(member.getId());
        String key = MemberConstant.MEMBER_INFO + member.getId();
        redisCache.setCacheObject(key, member, 1, TimeUnit.HOURS);
        return AjaxResult.success(member);

    }

    private Member updateIPMessageByMemberId(Integer memberId) {
        Member member1 = new Member();
        member1.setId(memberId);
        setIPMessage(member1);
        memberService.updateById(member1);
        return memberService.getById(memberId);
    }

    /**
     * 获取成员列表
     *
     * @return
     */
    @GetMapping("/getMemberList")
    public AjaxResult getMemberList() {
        LambdaUpdateWrapper<Member> lqw = new LambdaUpdateWrapper<Member>()
                .eq(Member::getStatus, "0");
        return AjaxResult.success(memberService.list(lqw));
    }

    /**
     * 上传接口
     *
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/upload")
    AjaxResult upload(@RequestBody MultipartFile file) throws IOException {
        String originalFilename = file.getOriginalFilename();
        ArrayList<String> strings = new ArrayList<>();
        strings.add(".jpg");
        strings.add(".png");
        String url = "http://picture.hibox.cloud/";
        // 后缀名
        String substring = originalFilename.substring(originalFilename.lastIndexOf("."));
        if (!strings.contains(substring)) {
            return AjaxResult.error("只能上传jpg/png文件，且不超过500kb");
        }
        String fileName = IdUtil.fastSimpleUUID() + substring;
        qiniuUtils.upload2Qiniu(file.getBytes(), fileName);
        return AjaxResult.success()
                .put("name", originalFilename)
                .put("file", url + fileName);
    }

    /**
     * 改变会员状态
     *
     * @param id
     * @param status
     * @return
     */
    @GetMapping("/changeMemberStatus")
    public AjaxResult changeMemberStatus(String id, String status) {
        LambdaUpdateWrapper<Member> lqw = new LambdaUpdateWrapper<Member>()
                .eq(Member::getId, id)
                .set(Member::getStatus, status);
        return memberService.update(lqw) ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 分页显示
     *
     * @param pageNum
     * @param pageSize
     * @param search
     * @param status
     * @param sex
     * @param loginDate
     * @return
     */
    @GetMapping("/list")
    public AjaxResult list(Long pageNum, Long pageSize, String search, String status, String sex, String loginDate) {
        Page<Member> memberPage = new Page<>(pageNum, pageSize);
        LambdaUpdateWrapper<Member> lqw = new LambdaUpdateWrapper<Member>()
                .eq(ObjectUtil.isNotEmpty(status), Member::getStatus, status)
                .eq(ObjectUtil.isNotEmpty(sex), Member::getSex, sex)
                .like(ObjectUtil.isNotEmpty(loginDate), Member::getLoginDate, loginDate);
        if (ObjectUtil.isNotEmpty(search)) {
            lqw.like(Member::getMemberName, search).or()
                    .like(Member::getNickName, search).or()
                    .like(Member::getPhone, search).or()
                    .like(Member::getEmail, search).or()
                    .like(Member::getIpAddress, search).or()
                    .like(Member::getLoginIp, search).or()
                    .like(Member::getPhoneAddress, search);
        }
        memberPage = memberService.page(memberPage, lqw);
        List<Member> records = memberPage.getRecords();
        if (ObjectUtil.isEmpty(records)) {
            return AjaxResult.success();
        }
        return AjaxResult.success()
                .put("rows", records)
                .put("total", memberPage.getTotal());
    }


    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("{id}")
    public AjaxResult selectOne(@PathVariable Serializable id) {
        Member byId = memberService.getById(id);
        return ObjectUtil.isNotEmpty(byId) ? AjaxResult.success(byId) : AjaxResult.error();
    }

    /**
     * 新增数据
     *
     * @param member 实体对象
     * @return 新增结果
     */
    @PostMapping
    public AjaxResult insert(@RequestBody Member member) {
        if (ObjectUtil.isEmpty(member.getNickName())) {
            return AjaxResult.error("昵称为空");
        }
        String email = member.getEmail();
        if (ObjectUtil.isNotEmpty(email)) {
            if (RegexUtils.isEmailInvalid(email)) {
                return AjaxResult.error("邮箱格式错误");
            }
            LambdaUpdateWrapper<Member> eq = new LambdaUpdateWrapper<Member>()
                    .eq(Member::getEmail, email);
            List<Member> list = memberService.list(eq);
            if (ObjectUtil.isNotEmpty(list)) {
                return AjaxResult.error("邮箱：" + email + "重复");
            }
        }
        String phone = member.getPhone();
        if (ObjectUtil.isNotEmpty(phone)) {
            if (RegexUtils.isPhoneInvalid(phone)) {
                return AjaxResult.error("手机号格式错误");
            }
            LambdaUpdateWrapper<Member> eq = new LambdaUpdateWrapper<Member>()
                    .eq(Member::getPhone, phone);
            List<Member> list = memberService.list(eq);
            if (ObjectUtil.isNotEmpty(list)) {
                return AjaxResult.error("手机号：" + phone + "重复");
            }
            // 手机号归属地
            String phoneAddress = PhoneAddress.getPhoneAddress(phone);
            member.setPhoneAddress(phoneAddress);
        }
        setIPMessage(member);

        if (StringUtils.isNotEmpty(Convert.toStr(member.getId()))) {
            return update(member);
        }
        // 账号
        String memberName = "Hi-Box" + IdUtils.fastSimpleUUID();
        member.setMemberName(memberName);
        // 密码 默认 8个8 加密
        String password = SecurityUtils.encryptPassword("88888888");
        member.setPassword(password);
        return memberService.save(member) ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 设置ip相关信息 IP 地址 登录时间
     *
     * @param member
     */
    private static void setIPMessage(Member member) {
        // 登录IP
        String loginIp = IpUtils.getIpAddr(ServletUtils.getRequest());
        member.setLoginIp(loginIp);
        // 登录IP地址
        String address = AddressUtils.getRealAddressByIP(loginIp);
        member.setIpAddress(address);
        // 登录时间
        member.setLoginDate(DateUtil.date());
    }

    @PutMapping("/updatePassword")
    public AjaxResult changePassowrd(@RequestBody Map map) {
        String password = map.get("password").toString();
        String memberId = map.get("memberId").toString();
        //  密码
        Member byId = memberService.getById(memberId);
        if (!SecurityUtils.matchesPassword(password, byId.getPassword())) {
            password = SecurityUtils.encryptPassword(password);
        }
        Member member = new Member();
        member.setId(Convert.toInt(memberId));
        member.setPassword(password);
        return memberService.updateById(member) ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 修改数据
     *
     * @param member 实体对象
     * @return 修改结果
     */
    @PutMapping
    public AjaxResult update(@RequestBody Member member) {
        Member byId = memberService.getById(member.getId());
        // 头像
        String avatar = member.getAvatar();
        // 原始头像
        String avatar1 = byId.getAvatar();
        if (StringUtils.isNotEmpty(avatar)) {
            if (!avatar.equalsIgnoreCase(avatar1)) {
                if (StringUtils.isNotEmpty(avatar1)) {
                    qiniuUtils.deleteFileFromQiniu(avatar1.substring(avatar1.lastIndexOf("/")).split("/")[1]);
                }
            }
        }
        return memberService.updateById(member) ? AjaxResult.success() : AjaxResult.error();
    }

    /**
     * 删除数据
     *
     * @param id 主键结合
     * @return 删除结果
     */
    @DeleteMapping("{id}")
    public AjaxResult delete(@PathVariable String id) {
        List<String> split = StrUtil.split(id, ",");
        List<Member> members = memberService.listByIds(split);
        if (ObjectUtil.isNotEmpty(members)) {
            for (Member member : members) {
                String avatar = member.getAvatar();
                qiniuUtils.deleteFileFromQiniu(avatar.substring(avatar.lastIndexOf("/")).split("/")[1]);
            }
        }
        return memberService.removeByIds(split) ? AjaxResult.success() : AjaxResult.error();
    }
}

